<template>
	<div class="pc-simulator" :class="{
		'pc-simulator-selected': page.selected
	}" @click="handleClickPage">
    <div
			v-show="showEmptyTip"
			class="page-empty"
		>
			<SvgIcon iconName="icon-link"></SvgIcon>
			<p class="text-warning-info">
				拖动左侧物料到此处生成页面
			</p>
		</div>
		<eForm style="height: 100%;" v-show="!showEmptyTip" v-bind="formProps">
			<draggable
				:list="list"
				group="dragsource"
				:sort="false"
				:animation="300"
				class="page-content"
				ghostClass="ghost"
				itemKey="id"
				@add="handleWidgetAdd"
			>
				<template #item="{ element }">
					<template v-if="element.drag && element.drag.classify && ['layout', 'page'].includes(element.drag.classify.value)">
						<div :class="['layout-section', { 'layout-section-selected': element.selected }]">
							<component
								:key="element.id"
								:is="getContainerTag(element.drag.compName)"
								v-bind="getValidProps(element.data.props)"
								@click.stop.native="handleClickElement(element)"
							>
								<component
									v-for="col in element.data.props.columns"
									:key="col.id"
									:is="getContainerTag(element.drag.compName, true)"
									v-bind="getValidProps(col)"
								>
									<draggable
										:list="col.list"
										group="dragsource"
										:sort="false"
										:animation="300"
										ghostClass="ghost"
										itemKey="id"
										:class="['widget-col-list', element.drag.compName === 'Grid' ? 'grid-ele' : 'container-ele']"
										@add="handleWidgetColAdd($event, col)"
									>
										<template #item="{ element: colEle }">
											<div class="ele-container" @click.stop="handleClickElement(colEle)">
												<div :class="['mask-layer', { 'ele-container-selected': colEle.selected }]"></div>
												<PageMakingItem v-bind="getParam(colEle)"></PageMakingItem>
												<SvgIcon v-show="colEle.selected" iconName="icon-closefill" className="del-icon" @click.stop="handleDeleteElement(element, col)"></SvgIcon>
											</div>
										</template>
									</draggable>
								</component>
							</component>
							<SvgIcon v-show="element.selected" iconName="icon-closefill" className="del-icon" @click.stop="handleDeleteElement(element)"></SvgIcon>
						</div>
					</template>
					<div v-else class="ele-container" @click.stop="handleClickElement(element)">
						<div :class="['mask-layer', { 'ele-container-selected': element.selected }]"></div>
						<PageMakingItem v-bind="getParam(element)"></PageMakingItem>
						<SvgIcon v-show="element.selected" iconName="icon-closefill" className="del-icon" @click.stop="handleDeleteElement(element)"></SvgIcon>
					</div>
				</template>
			</draggable>
		</eForm>
  </div>
</template>

<script setup lang="ts">
import draggable from 'vuedraggable'
import { computed, reactive, ref, watch } from 'vue'
import useDrag from '@/hooks/viewEditor/useDrag'
import { getConfig, restoreConfig } from '@/hooks/viewEditor/useUtil'
import { convertValue, getContainerTag, getValidProps } from '@/hooks/pageMaking/useUtil'

interface IProps {
	dragging: boolean,
	initJson?: Record<string, any>
}

const props = defineProps<IProps>()

const { 
	list, showEmptyTip, page, compUUID,
	handleWidgetAdd, handleClickElement, handleDeleteElement,
	handleClickPage, handleWidgetColAdd
} = useDrag(props)

const formProps = computed(() => getValidProps((page.data as any)?.props || {}))
function getParam(item: any) {
	const model = item.data.dataModel?.model || ''
	const res: Record<string, any> = {
		key: item.id,
		options: {
			label: item.data.props._compLabel,
			component: item.drag.compName,
			props: JSON.parse(JSON.stringify(item.data.props)),
			events: item.data.events || {},
			slots: item.data.slots || {},
			dataModel: item.data.dataModel || {},
			model
		},
		models: {},
		isDragMode: true
	}
	if (model) {
		res.models[model] = convertValue({ ...item.data, component: item.drag.compName })
	}
	return res
}

watch(
	() => props.initJson,
	(newVal) => {
		if (newVal) {
			restoreConfig(newVal, page, list, compUUID)
		}
	}
)

defineExpose({ 
	getConfig: () => getConfig(page, list.value)
})

</script>

<style lang="less" scoped>
.pc-simulator {
	width: 100%;
	height: 100%;
	background-color: #ffffff;
	font-size: 12px;
	overflow: hidden;
	box-shadow: 0 0 10px #8d8d8d;
	&-selected {
		box-shadow: 0 0 8px #4d72dd;
	}
}
.page-empty {
	height: 100%;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	font-size: 18px;
	color: #4d72dd;
	.text-warning-info {
		margin-top: 24px;
	}
}
.page-content {
	height: 100%;
	padding: 8px;
	box-sizing: border-box;
	overflow-y: auto;
	position: relative;
	.layout-section {
		position: relative;
		margin: 8px;
		min-height: 48px;
		padding: 4px 0;
		box-sizing: border-box;
		&-selected {
			box-shadow: 0 0 4px #1339c3;
		}
	}
	.ele-container {
		border: 1px solid #e6e8eb;
    position: relative;
		margin: 8px;
		padding: 4px;
		background-color: #ffffff;
		&-selected {
			box-shadow: 0 0 4px #8d0776;
		}
	}
	.mask-layer {
		position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
	}
	.del-icon {
		position: absolute;
    right: -0.75em;
    top: -0.75em;
		color: #8d0776;
		cursor: pointer;
	}
	.widget-col-list {
		height: 100%;
		min-height: 40px;
		padding: 4px;
		box-sizing: border-box;
		.ele-container {
			margin: 0 !important;
		}
	}
	.grid-ele {
		background-color: #e5e5e5;
	}
}
</style>
